﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Bson.Serialization;
using MongoDB.Driver.Linq;
using MongoDB.Bson.Serialization.Attributes;
namespace asMeishi.web.Models
{
    public class comment : MongoDocument
    {
        /// <summary>
        /// 评论内容
        /// </summary>
        [BsonElement("CT")]
        public string content{get;set;}
        /// <summary>
        /// 推荐菜的jsonstr
        /// [{id:"菜id",name:"菜名"},{id:"菜id",name:"菜名"}]
        /// </summary>
        [BsonElement("F")]
        public string food { get; set; }
        /// <summary>
        /// 质量
        /// </summary>
        [BsonElement("Q")]
        public int? quality { get; set; }
        /// <summary>
        /// 服务
        /// </summary>
        [BsonElement("S")]
        public int? service { get; set; }
        /// <summary>
        /// 赞同数
        /// </summary>
        [BsonElement("A")]
        public int argeeNum { get; set; }
        /// <summary>
        /// 反对数
        /// </summary>
        [BsonElement("O")]
        public int opposeNum { get; set; }
        /// <summary>
        /// 环境
        /// </summary>
        [BsonElement("E")]
        public int? priceQuality { get; set; }
        /// <summary>
        /// 
        /// </summary>
        [BsonElement("TID")]
        public ObjectId targetId { get; set; }

        /// <summary>
        /// 花费
        /// </summary>
        [BsonElement("C")]
        public int? cost { get; set; }
        [BsonElement("UID")]
        public ObjectId userId { get; set; }
        /// <summary>
        /// 用户昵称 暂时未使用
        /// </summary>
        [BsonElement("UN")]
        public string userName { get; set; }

        [BsonElement("DT")]
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime datetime { get; set; }

        /// <summary>
        /// 0:未发布，1：发布
        /// </summary>
        [BsonDefaultValue(1)]
        [BsonElement("RL")]
        public int release { get; set; }
    }


    public class commentC
    {
        DataSession<MongoDataContext, comment> db = new DataSession<MongoDataContext, comment>();
        
        public comment createDefault(user user) {
            comment comment = new comment();
            comment.food = "";
            comment.datetime = DateTime.Now;
            comment.userId = user.Id;
            comment.userName = user.name;
            return comment;
        }
        /// <summary>
        /// 如果参数为假返回全部记录包话无效的没发布的
        /// </summary>
        /// <param name="shopStatus"></param>
        /// <returns></returns>
        public IQueryable<comment> getAll(Boolean shopStatus = true)
        {
            if (shopStatus == true)
            {
                return db.query.Where(d =>  d.release == 1);
            }
            else
            {
                return db.query;
            }
        }
        /// <summary>
        /// 统计分数
        /// </summary>
        /// <param name="shopId"></param>
        /// <returns></returns>
        public MapReduceResult statisticsScore(ObjectId shopId){
            BsonJavaScript map = new BsonJavaScript(
                @"function Map(){
                    if(this.Q>0 && this.TID=='" + shopId.ToString() +@"'){
                        emit('score',{Q:this.Q,S:this.S,E:this.E,count:1,totalScore:(this.Q+this.S+this.E)});
                    }
        
                }"
            );
            BsonJavaScript reduce = new BsonJavaScript(
                @"function Reduce(key,values){
                    var Q=0;
                    var S=0;
                    var E=0;
                    var count=0;
                    var totalScore=0;
                    values.forEach(function(doc){
                        totalScore += doc.Q+doc.S+doc.E;
                        Q += doc.Q;
                        S += doc.S;
                        E += doc.E;
                    });
                    return {Q:Q/values.length,S:S/values.length,E:E/values.length,count:values.length,totalScore:totalScore}
                }"

            );
               
                return db.Mquery.MapReduce(map, reduce);



        }
        /// <summary>
        /// 统计消费
        /// </summary>
        /// <param name="shopId"></param>
        /// <returns></returns>
        public MapReduceResult statisticsCost(ObjectId shopId)
        {
            BsonJavaScript map = new BsonJavaScript(
                @"function Map(){
                    if(this.C>0 && this.TID=='" + shopId.ToString() + @"'){
                        emit('score',{C:this.C,count:1});
                    }
        
                }"
            );
            BsonJavaScript reduce = new BsonJavaScript(
                @"function Reduce(key,values){
                    var C=0;

                    values.forEach(function(doc){
                        C += doc.C;
                    });
                    return {C:C/values.length,count:values.length}
                }"

            );

            return db.Mquery.MapReduce(map, reduce);



        }
        public comment create(ObjectId Id, string content,int? cost, int? quality, int? service,int? priceQuality, user user, DateTime dt, int release = 1)
        {
            var comment = createDefault(user);
            comment.targetId =Id;
            comment.release = release;
            comment.cost = cost;
            comment.content = content;
            comment.quality = quality;
            comment.service = service;
            comment.priceQuality = priceQuality;
            return comment;
        }
        public void add(comment c)
        {
            db.Add(c);
        }
        public comment get(string id) {
            return db.GetById(id);
        }
        public void del(string id){
            db.Delete(id);
        }
        
        public IQueryable<comment> getByShopId(ObjectId shopId) {
           //return db.findOne(shopId);
           return db.Where(d => d.targetId == shopId);
        }

        public IQueryable<comment> getTopByDate()
        {
            return db.query.OrderByDescending(d => d.datetime);
        }

        public void updateFood(ref comment comment, string str) {
            if (string.IsNullOrWhiteSpace(str)) { comment.food = "";  };
            comment.food = str;

        }
        public int? getService(ObjectId shopId)
        {
            return db.Where(d => d.targetId == shopId).Sum(d => d.service);

        }
        public int? getQuality(ObjectId shopId)
        {
            return db.Where(d => d.targetId == shopId).Sum(d => d.quality);
        }
        public int? getEnvironment(ObjectId shopId)
        {
            return db.Where(d => d.targetId == shopId).Sum(d => d.priceQuality);
        }
        public int? getCost(ObjectId shopId)
        {
            return db.Where(d => d.targetId == shopId).Sum(d => d.cost);
        }
        public void save(comment comment)
        {
            db.Save(comment);
        }
    }
}
